# -*- coding=utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import tornado.web
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.httpserver
import os.path,os,datetime,sys,time,codecs
import markdown
import json
import codecs
try:
    import cPickle as pickle
except:
    import pickle

from hashlib import sha256
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
create_sessionkey= lambda: sha256('%s%s' % (os.urandom(16),time.time())).hexdigest()
session_container = {}

class data(object):
    def __init__(self,fname):
        self.fname = fname

    def get(self):
        try:
            with codecs.open(self.fname, 'rb', 'utf-8') as fp:
                text = fp.read()
                data = pickle.loads(str(text))
        except Exception as e:
            return False,e
        else:
            return True,data

    def update(self,Data):
        try:
            with codecs.open(self.fname,'wb','utf-8') as fp:
                pickle.dump(Data,fp,True)
        except Exception as e:
            return False,e
        else:
            return True,'OK'

class session(object):
    def __init__(self,request):
        sessionid = '__sessionid__'
        self._request = request
        self._id = request.get_cookie(sessionid,'')
        if not self._id:
            self._id = create_sessionkey()
            request.set_cookie(sessionid,self._id,expires_days=None,expires=time.time()+900)

    def __getitem__(self,item):
        return session_container[self._id][item]
    
    def __setitem__(self,item,value):
        if session_container.has_key(self._id):
            session_container[self._id][item] = value
        else:
            session_container[self._id] = {item:value}

    def __delitem__(self,item):
        del(session_container[self._id])

class footer(tornado.web.UIModule):
    def render(self,link):
        return self.render_string('footer.html',link=link)

settings = {
    "static_path" : os.path.join(os.path.dirname(__file__), "./static/"),
    "template_path" : os.path.join(os.path.dirname(__file__), "./templates/"),
    "xsrf_cookies" : True,
    "login_url": "/login",
    "ui_modules":{"footer":footer},
    "debug": True}

class BaseHandler(tornado.web.RequestHandler):
    def initialize(self):
        self.session = session(self)
        self.IP = self.request.remote_ip
        self.cf = data('config.pk')
        status, result = self.cf.get()
        if status:
            self.data = result
            self.article = self.data['article']
        else:
            self.send_error(404)

    def get_current_user(self):
        sessionid = self.get_cookie('__sessionid__',False)
        if sessionid and session_container.has_key(sessionid):
            if self.session['IP'] == self.IP:
                return True
            else:
                return False
        else:
            return False

    def convert(self,ID,short=False):
        MD_File = './md/%s/index.md' % ID
        if os.path.exists(MD_File):
            with codecs.open(MD_File, 'r', 'utf-8') as f:
                md = markdown.Markdown(extensions=['markdown.extensions.toc',
                                                   'markdown.extensions.tables',
                                                   'markdown.extensions.fenced_code',
                                                   'markdown.extensions.footnotes'])
                if short:
                    html = md.convert(f.read()[0:100])
                else:
                    html = md.convert(f.read())
                return html
        else:
            return False

    @property
    def save(self):
        try:
            self.cf.update(self.data)
        except Exception as e:
            return False,e
        return True,'OK'

class index(BaseHandler):
    def get(self,url=''):
        link = self.data.get('link')
        subtitle = self.data.get('subtitle')
        name = self.data.get('blog_name')
        if not url:
            description = self.data.get('description')
            keywords = self.data.get('keywords')
            article = self.article.items()
            name = self.data['blog_name']
            html = {}
            for i in article:
                html[i[0]]=self.convert(i[0],short=True)
            #count = len(article)
            self.render('index.html',name = name,title=name,article = article,subtitle=subtitle,
                        description = description,keywords = keywords,html = html,link=link)
        else:
            articles = self.article.get(url)
            if articles:
                article = articles['title']
                Date = articles['Date']
                group = articles['group']
                title = name + '-' + article
                arg = articles['arg']
                html = self.convert(url)
                self.render('page.html',name = name,title = title,subtitle=subtitle,description = '',link=link,
                            keywords = arg,article = article,html = html,ID = url,Date = Date,group = group)
            else:
                self.send_error(404)

class admin(BaseHandler):
    #@tornado.web.authenticated
    def get(self,handle=None):
        if not handle:
            self.render('global.html',link = self.data.get('link'),
                        subtitle=self.data.get('subtitle'),
                        name=self.data.get('blog_name'),
                        keywords=self.data.get('keywords'),
                        duoshuo=self.data.get('duoshuo'),
                        description=self.data.get('description'))
        elif handle == '/user':
            self.render('user.html', link=self.data.get('link'),
                        subtitle=self.data.get('subtitle'),
                        name=self.data.get('blog_name'),
                        )
        elif handle == '/article':
            self.render('article.html', link=self.data.get('link'),
                        subtitle=self.data.get('subtitle'),
                        name=self.data.get('blog_name'),
                        article=self.article
                        )
        else:
            self.send_error(404)

    def post(self,handle=None):
        args = dict(
        name = self.get_argument('blog_name',''),
        subtitle = self.get_argument('subtitle',''),
        keywords = self.get_argument('keywords',''),
        description = self.get_argument('description',''),
        duoshuo = self.get_argument('duoshuo',''))
        self.data.update(args)
        self.save
        self.redirect('/admin')

class link(BaseHandler):
    def post(self):
        linkid = self.get_argument('id','')
        handle = self.get_argument('type','')
        linkname = self.get_argument('linkname','')
        linkurl = self.get_argument('linkurl','')
        try:
            if linkid and int(linkid) in self.data['link'].keys():
                if handle == 'del':
                    del self.data['link'][int(linkid)]
                elif handle == 'edit':
                    self.data['link'][int(linkid)]=(linkname,linkurl)
            elif handle == 'add':
                ID = min(list(set(self.data['link'].keys()) ^ set(xrange(1,1000))))
                print ID
                self.data['link'][ID] = (linkname, linkurl)
            else:
                self.write('Wrong parameter！')
            self.save
        except Exception as e:
            self.write('操作发生问题：%s' % e)
        else:
            self.redirect('/admin')


class delete(BaseHandler):         #文章删除
    @tornado.web.authenticated
    def get(self):
        ID = self.get_argument('ID','')
        try:
            os.remove('md/%s' % ID)
            del self.article[ID]
        except Exception as e:
            self.write(0)
        else:
            self.cf.update(self.data)
            self.write(1)

class userupdate(BaseHandler):     #用户管理
    @tornado.web.authenticated
    def post(self):
        user = self.get_secure_cookie("WLBLOG")
        username=self.get_argument('newuser','')
        oldpwd=self.get_argument('oldpwd','')
        pwd1=self.get_argument('pwd1','')

class upload(BaseHandler):
    @tornado.web.authenticated
    def post(self):
        upload_path=os.path.join(os.path.dirname(__file__),'static/image/')
        file_metas = self.request.files['editormd-image-file']
        filename = ''
        for meta in file_metas:
            filename=time.strftime("%Y%m%d%H%M%S", time.localtime()) + meta['filename']
            filepath=os.path.join(upload_path,filename)
            with open(filepath,'wb') as up:
                up.write(meta['body'])
        s = {'success':1,'message': 'OK','url':'static/image/%s' % filename}
        self.write(json.dumps(s))
        
class login(BaseHandler):
    def get(self):
        if self.get_current_user():
            self.redirect("/admin")
        else:
            self.render("login.html")

    def post(self):
        username = self.get_argument('username','')
        password = self.get_argument('password','')
        if self.data['user'].get(username)==password:
            self.session['IP']= self.IP
            self.session['username'] = username
            self.redirect('/admin')
        else:
            self.redirect('/login')

class logout(tornado.web.RequestHandler):
    def get(self):
        self.clear_all_cookies()
        self.redirect("/")

App = tornado.web.Application([
    (r'/',index),
    (r'/([0-9]+)$',index),
    (r'/admin(/article|/user|)',admin),
    (r'/link',link),
    (r'/login',login),
    (r'/logout',logout)
    ],**settings)
if __name__ == "__main__":
    tornado.options.define("port", default=80, help="Run server on a specific port", type=int)
    tornado.options.parse_command_line()
    http_server = tornado.httpserver.HTTPServer(App)
    http_server.listen(tornado.options.options.port)
    tornado.ioloop.IOLoop.instance().start()